/**
 * request
 * {
 *      tool: 'chatglm',
 *      server_tool: '',
 *      exec_params: '',
 *      compile_params: '',
 *      code: '',
 *      prompt: '',
 *      id: '', // 用于标识不同的的对话
 * }
 *
 * response
 * {
 *      status: 0 | 1,
 *      content:
 *      tool: '', // 将最佳结果的工具返回，多次转译选择自动的时候，第二次之后则使用次工具进行多次询问 
 *      error:
 *      id: ''
 * }
 * 
 * 用于自动转译，由于需要多个结果进行对比，所以效率会比较低
 * 工具选择优先级：
 * 0. 数据库已经通过的记录
 * 1. c2rust工具
 * 2. chatgpt4 (暂未接入)
 * 3. 其他大模型
*/

// import c2rust from './tools/c2rust.js';
import { chatglm } from './tools/chatglm.js';
import { baichuan } from './tools/baichuan.js';
import run from './tools/run.js';

import TranspileRecord from './db/TranspileRecord.js';
import { chatgpt4 } from './tools/chatgpt4.js';


export default async function auto_transcode(req, res, repeat_count) {
    // console.log('[auto_transcode] ', req.body);

    // 编译/执行C代码
    // 如果c代码编译/执行错误，则直接返回错误信息，不进行转译
    let c_stdout = '';
    try {
        c_stdout = await run.c(
            req.body.code,
            req.body.compile_params || '',
            req.body.exec_params || ''
        );
    } catch (e) {
        res.send({
            status: 1,
            error: "C代码编译/执行错误: " + e,
            id: req.body.id
        })
        return;
    }

    // 其他工具并行进行转译
    let rust_codes = [
        /*
        {
            tool: ''
            content: ''
        }
        */
    ]


    try {
        //只保留chatgpt4
        // const tool_order = ['baichuan', 'chatglm'];
        // const bc = baichuan(req.body);
        // const cg = chatglm(req.body);
        // const results = await Promise.allSettled([bc, cg]);
        const tool_order = ['chatgpt4'];
        // ! linux测试打开，后续需要检查
        const chat = chatgpt4(req.body)
        const results = await Promise.allSettled([chat]);
        results.forEach((result, idx) => {
            if (result.status === 'fulfilled') {
                rust_codes.push({
                    tool: tool_order[idx],
                    content: result.value
                })
            }
        })
        // console.log('rust_codes:', rust_codes);
    } catch (e) {
        res.send({
            status: 1,
            error: "AI大模型调用错误: " + e,
            id: req.body.id
        })
        return;
    }

    // 执行不同大模型给出的结果

    // 统一C和rust的换行符
    c_stdout = (c_stdout || '').replace(/\r\n/g, "\n").trim();
    try {
        const tool_order = [];
        const promises = rust_codes.map(async (item) => {
            const { tool, content } = item;
            tool_order.push(tool);
            return run.rust(content, req.body.exec_params);
        })
        const results = await Promise.allSettled(promises);

        // 运行未出错，但结果对不上的代码
        const run_success_code = [
            // {
            //     tool: '',
            //     content: ''
            // }
        ];
        // 成功运行，且结果一致的代码
        const pass_code = [
            // {
            //     tool: '',
            //     content: ''
            // }
        ];
        // 运行失败的代码
        const failed_code = [
            /*
            {
                tool: ''
                content: ''
            }
            */
        ];
        results.forEach((result, idx) => {
            // 对比结果，选择最佳结果
            if (result.status === 'fulfilled') {
                // 成功运行，对比结果
                const r_stdout = (result.value || '').replace(/\r\n/g, "\n").trim();
                if (c_stdout === r_stdout) {
                    // 结果一致
                    pass_code.push({
                        tool: tool_order[idx],
                        content: rust_codes[idx].content
                    })
                } else {
                    // 结果不一致，但通过编译
                    run_success_code.push({
                        tool: tool_order[idx],
                        content: rust_codes[idx].content
                    })
                }
            } else {
                // 运行失败，如果最终没有成功的结果，则从需要从失败的结果中选择最佳结果(TODO 最佳的判断标准？)
                failed_code.push({
                    tool: tool_order[idx],
                    content: rust_codes[idx].content
                })
            }
        })

        // console.log("pass_code: ", pass_code);
        // console.log("run_success_code: ", run_success_code);
        // console.log("failed_code: ", failed_code);

        if (pass_code.length > 0) {
            let best = pass_code[0];
            // if (pass_code.length === 1) {
            //     // 只有一个选一个
            //     best = pass_code[0];
            // } else {
            //     // 如果有多个, 不选c2rust
            //     best = pass_code.filter(item => item.tool !== 'c2rust')[0];
            // }
            res.send({
                status: 0,
                content: best.content,
                tool: best.tool,
                id: req.body.id
            })
            // 存入数据库
            await TranspileRecord.createOrUpdate((req.body.code || '').trim(), (best.content || '').trim());

            return;
        }
        if (run_success_code.length > 0) {
            res.send({
                status: 0,
                content: run_success_code[0].content,
                tool: run_success_code[0].tool,
                id: req.body.id
            })
            await TranspileRecord.createOrUpdate((req.body.code || '').trim(), (run_success_code[0].content || '').trim(), false);

            return;
        }

        if (failed_code.length > 0) {
            res.send({
                status: 0,
                content: failed_code[0].content,
                tool: failed_code[0].tool,
                id: req.body.id
            })
            await TranspileRecord.createOrUpdate((req.body.code || '').trim(), (failed_code[0].content || '').trim(), false);

            return;
        }
    } catch (e) {
        console.log('---------------------------')
        console.log(e);
        console.log('---------------------------')

        // 理论上不可能出现
        res.send({
            status: 1,
            error: "生成代码测试编译/运行错误: " + e,
            id: req.body.id
        })
        return;
    }



    // res.send({
    //     status: 0,
    //     content: "// auto testing",
    //     id: req.body.id
    // })

    // 理论上不可能出现
    res.send({
        status: 1,
        error: "服务不可用",
        id: req.body.id
    })
}